#!/usr/bin/env node

const {program} = require("commander");
const package_json = require("../package.json");
const fs = require("fs");
const path = require("path");
const cluster = require('cluster');
const os = require('os');
const {findNodeModulesAllPacksPath, packModule} = require("./utils/index.js");

program.version(
  package_json.version,
  "-v, --version",
  "Output the current version"
);




program
  .command("build",'packs node_modules direction.')
  .alias("buil")
  .alias("bui")
  .alias("bu")
  .alias("b")
  .description(
    "List all dependencies and create npm pack in the specified directory"
  )
  .option("-o, --output <directory>", "Specify the output directory", "packs")
  .option(
    "-i, --ignore <packages>",
    "Specify packages to ignore (comma-separated)",
    ""
  ).option(
  "-w, --workers <number>",
  "Specify number of worker processes to use",
  (val) => parseInt(val, 10),
  os.cpus().length // 默认使用 CPU 核心数
)
  .action((options) => {
    const outputDir = path.isAbsolute(options.output)
      ? options.output
      : path.join(process.cwd(), options.output);

    const allPackPath = findNodeModulesAllPacksPath();
    const allPackPathLen = allPackPath.length;

    let completed = 0;
    let successful = 0;
    let failed = 0;

    if (cluster.isMaster) {
      for (let i = 0; i < Math.min(options.workers, allPackPathLen); i++) {
        const worker = cluster.fork()
        worker.on('online', () => {
          if (allPackPath.length > 0) {
            const currentPack = allPackPath.shift()
            console.log('Packing：',currentPack)
            worker.send({
              type: 'pack',
              path: currentPack,
              outputDir
            })
          } else {
            worker.send({type: 'exit'});
          }

        })

        worker.on('message', (msg) => {
          const {type} = msg
          if (type === "result") {
            completed++;
            if (msg.status === 'success') {
              successful++;
              //  检查是否还有任务
              if (allPackPath.length > 0) {
                const currentPack = allPackPath.shift()
                console.log('Packing：',currentPack)
                worker.send({
                  type: 'pack',
                  path: currentPack,
                  outputDir
                })
              } else {
                worker.send({type: 'exit'});
              }

              if (completed === allPackPathLen) {
                // 退出所有工作进程
                for (const id in cluster.workers) {
                  cluster.workers[id].send({type: 'exit'});
                }
                console.log(`
                  successful: ${successful},
                  failed: ${failed},
                  completed: ${completed}
                `)
              }
            } else {
              failed++;
            }
          }
        })
      }
    } else {
      process.on('message', async (data) => {
        const {type} = data;
        if (type === 'pack') {
          try {
            const result = await packModule(data.path, data.outputDir);
            process.send({
              type: 'result',
              status: 'success',
              result
            });
          } catch (err) {
            process.send({
              type: 'result',
              status: 'error',
              result: {
                success: false,
              }
            });
          }

        } else if (type === 'exit') {
          process.exit(0)

        }
      })
      // 通知主进程工作进程已准备好
      process.send({type: 'ready'});
    }

  });

program
  .command("clean")
  .description("Clean the specified output directory of .tgz files")
  .option("-o, --output <directory>", "Specify the directory to clean", "packs")
  .action((options) => {
    const outputDir = path.isAbsolute(options.output)
      ? options.output
      : path.join(process.cwd(), options.output);

    if (fs.existsSync(outputDir)) {
      let deletedCount = 0;
      fs.readdirSync(outputDir).forEach((file) => {
        const filePath = path.join(outputDir, file);
        if (path.extname(file) === ".tgz") {
          fs.unlinkSync(filePath);
          console.log(`Deleted ${filePath}`);
          deletedCount++;
        }
      });

      if (deletedCount === 0) {
        console.log("No .tgz files found to delete.");
      } else {
        console.log("-----");
        console.log(`Total .tgz files deleted: ${deletedCount}`);
      }
    } else {
      console.log(`The directory ${outputDir} does not exist.`);
    }
  });

program.parse(process.argv);
